/**
 * @file:          Protection.h
 * @brief:
 * @details:
 * @author:        wjh
 * @date created:  2023.06.19
 * @version:       1.0.0
 * @par copyright (c):
 *
 * @par history (desc):
 *   version:1.0.0, wjh, 2023.06.19,16:45:54
 */

#ifndef _PROTECTION_H_
#define _PROTECTION_H_

/* Include Files **************************************************************/
#include "Datatype.h"

/* Macro Definition ***********************************************************/
/* protection code version */
#define PROTECTION_VERSION_MAJOR ((uint8_t)1)
#define PROTECTION_VERSION_MINOR ((uint8_t)2)
#define PROTECTION_RELEASE_DATE ("2024-05-13 16:01:52")

/* err code define */
#define ERR_MAX_SIZE 32
#define ERR_MSG_LENGTH 30

#define ERR_NUM_ENCODER_MUTATION (0)                           /* 编码器跳变 */
#define ERR_NUM_ENCODER_READ_ERR (1)                           /* 编码器读取错误 */
#define ERR_NUM_SOFTWARE_PEAK_CURRENT_OVER_LIMIT (2)           /* 软件触发峰值过流 */
#define ERR_NUM_SOFTWARE_CONTINUE_CURRENT_OVER_LIMIT (3)       /* 软件触发持续过流 */
#define ERR_NUM_HARDWARE_CURRENT_OVER_LIMIT (4)                /* 硬件触发过流 */
#define ERR_NUM_SPEED_FDB_CONTINUE_OVER_LIMIT (5)              /* 速度持续超限 */
#define ERR_NUM_POS_FDB_OVER_LIMIT (6)                         /* 位置超限 */
#define ERR_NUM_POS_CMD_MUTATION (7)                           /* 位置指令跳变 */
#define ERR_NUM_EXCESSIVE_POS_TRACKING_ERROR (8)               /* 位置跟踪误差过大 */
#define ERR_NUM_MOTOR_CHECK_ValueAbnormal (9)                  /* 电阻电感值异常 */
#define ERR_NUM_MOTOR_CHECK_UnStable (10)                      /* 阶跃响应还没稳定*/
#define ERR_NUM_MOTOR_CHECK_MotorPhaseNotConnected (11)        /* 电机没有连接 */
#define ERR_NUM_MOTOR_CHECK_MotorPhaseResistanceDifferent (12) /* 两相电阻偏差过大（电机线圈短路）*/
#define ERR_NUM_MOTOR_CHECK_OtherErr (13)                      /* 电阻检查中的其他错误*/

/* warning code define */
#define WARN_MAX_SIZE 3
#define WARN_MSG_LENGTH 10

#define WARN_NUM_COMMUNICATION_ERR (0)          /* 通讯错误 */
#define WARN_NUM_MOTOR_POWER_SUPPLY_TOO_LOW (1) /* 电源电压过低 */
#define WARN_NUM_MCU_OVER_HEATING (2)           /* MCU温度过高 */

// #define ERR_NUM_COMMUNICATION_ERR (0)          /* 通讯错误 */
// #define ERR_NUM_MOTOR_POWER_SUPPLY_TOO_LOW (1) /* 电源电压过低 */
// #define ERR_NUM_MCU_OVER_HEATING (2)           /* MCU温度过高 */
// #define WARNING_NUM_OVER_HEAT (1)
// #define WARNING_NUM_ISR_OVER_RUN (2)

#define PROTECTION_CODE(num) (0x01UL << (num))

/* Data Type Define ***********************************************************/

typedef struct Protection
{
    /* public data */
    struct
    {
        union
        {
            uint16_t all;
            struct
            {
                uint8_t minor;
                uint8_t major;
            } byte;
        } number;
        char *release_date;
    } param_version;

    uint16 param_en;
    uint16 param_enable_report;
    float32 param_check_period_s;
    uint32 param_err_code_mask;
    uint32 param_warning_code_mask;

    float32 param_encoder_mutation_coefficient_upper;
    float32 param_encoder_mutation_coefficient_lower;
    float32 param_peak_overcurrent_A;
    float32 param_continuous_overcurrent_A;
    float32 param_continuous_overcurrent_time_s;
    float32 param_continuous_overcurrent_clear_time_s;
    float32 param_speed_over_limit_rad_s;
    float32 param_speed_over_limit_time_s;
    float32 param_pos_over_limit_max_rad;
    float32 param_pos_over_limit_min_rad;
    float32 param_pos_cmd_mutation_turns;
    float32 param_pos_tracking_error_maximum_rad; /* unit: rad */
    float32 param_pos_tracking_error_time_s;
    float32 param_power_voltage_min;
    float32 param_mcu_temp_max;

    uint32 continuous_overcurrent_count;
    uint32 continuous_overcurrent_count_max;
    uint32 continuous_overcurrent_clear_count;
    uint32 continuous_overcurrent_clear_count_max;
    uint32 continuous_overspeed_count;
    uint32 continuous_overspeed_count_max;
    uint32 continuous_pos_tracking_error_count;
    uint32 continuous_pos_tracking_error_count_max;
    int32 param_encoder_mutation_upper_encoder_pulse;
    int32 param_encoder_mutation_lower_encoder_pulse;

    uint32 err_code_raw;
    uint32 err_code;
    uint32 err_code_last;
    uint32 err_code_backup;
    uint32 warning_code_raw;
    uint32 warning_code;
    uint32 warning_code_last;
    uint32 warning_code_backup;

    const uint8 (*err_msg)[ERR_MSG_LENGTH];
    const uint8 (*warning_msg)[WARN_MSG_LENGTH];

    /* private data */

    /* public method */
    uint8 (*Init)(struct Protection *self);
    void (*ReportErr)(struct Protection *self);
    void (*ReportWarning)(struct Protection *self);
    void (*ClearErr)(struct Protection *self, uint16 err_num);
    void (*ClearWarning)(struct Protection *self, uint16 warnning_num);
    void (*SetErr)(struct Protection *self, uint16 err_code);
    void (*SetWarning)(struct Protection *self, uint16 warnning_code);
    void (*UpdateParam)(struct Protection *self);
    void (*ErrParsing)(struct Protection *self, uint32_t err_code);
    void (*WarningParsing)(struct Protection *self, uint32_t warning_code);

} Protection;

/* Variable Declare ***********************************************************/
extern const uint8 protection_err_msg[ERR_MAX_SIZE][ERR_MSG_LENGTH];
extern const uint8 protection_warning_msg[WARN_MAX_SIZE][WARN_MSG_LENGTH];

/* Function Declare ***********************************************************/
uint8 Protection_Init(struct Protection *self);
void Protection_ReportErr(struct Protection *self);
void Protection_ReportWarning(struct Protection *self);
void Protection_ClearErr(struct Protection *self, uint16 err_num);
void Protection_ClearWarning(struct Protection *self, uint16 warnning_num);
void Protection_SetErr(struct Protection *self, uint16 err_code);
void Protection_SetWarning(struct Protection *self, uint16 warnning_code);
void Protection_UpdateParam(struct Protection *self);
void Protection_ErrParsing(struct Protection *self, uint32_t err_code);
void Protection_WarningParsing(struct Protection *self, uint32_t warning_code);
#endif